/**
 * @description dorado工具箱sidebar页面
 * @author hans
 * @date 2025/5/28
 */
import * as vscode from "vscode";
import * as path from "path";
import * as fs from "fs";

// 使用Map存储不同类型的webview面板，key为viewType，value为panel实例
const panelMap: Map<string, vscode.WebviewPanel> = new Map();

export class SideBarWebviewProvider implements vscode.WebviewViewProvider {
  private context: vscode.ExtensionContext;
  constructor(context: vscode.ExtensionContext) {
    this.context = context;
  }
  async resolveWebviewView(
    webviewView: vscode.WebviewView,
    context: vscode.WebviewViewResolveContext,
    token: vscode.CancellationToken
  ) {
    webviewView.webview.options = {
      enableScripts: true,
    };
    let htmlContent = await this.getWebviewContent();
    //  替换html中的资源引用路径为https://格式
    const resourceUris = this.getResourceUris(webviewView);
    htmlContent = htmlContent
      .replace("${chunkVendorsUri}", resourceUris.chunkVendors.toString())
      .replace("${myJsUri}", resourceUris.sideBarJs.toString())
      .replace("${cssUri}", resourceUris.css.toString());

    webviewView.webview.html = htmlContent;
    //  接收webView端发送的消息，与vscode插件交互代码逻辑
    webviewView.webview.onDidReceiveMessage(
      (message) => {
        console.log("Received message:", message);
        // 'openCodeAssistant' | 'openAIProgrammer' | 'openFormDesigner';
        const command = message.command;
        switch (command) {
          case "openCodeAssistant":
            // 打开代码助手面板
            this.createWebviewPanel(
              "codeAssistant",
              "代码助手",
              "codeAssistantJs"
            );
            return;
          case "openAIProgrammer":
            // 打开AI程序员面板
            this.createWebviewPanel(
              "aiProgrammer",
              "AI程序员",
              "aiProgrammerJs"
            );
            return;
          case "openFormDesigner":
            // 打开表单设计器面板
            this.createWebviewPanel(
              "formDesigner",
              "表单设计器",
              "formDesignerJs"
            );
            return;
          default:
            vscode.window.showWarningMessage("Unknown command:" + command);
            return;
        }
      },
      undefined,
      this.context.subscriptions
    );
  }

  /**
   * 创建webview面板
   */
  public async createWebviewPanel(
    viewType: string,
    title: string,
    jsResourceKey: keyof ReturnType<typeof this.getPanelResourceUris>
  ) {
    // 如果同名面板已存在，则显示它而不是创建新的
    const existingPanel = panelMap.get(viewType);
    if (existingPanel) {
      existingPanel.reveal(vscode.ViewColumn.One);
      return;
    }

    // 创建新的webview面板
    const panel = vscode.window.createWebviewPanel(
      viewType,
      title,
      vscode.ViewColumn.One,
      {
        enableScripts: true,
        retainContextWhenHidden: true,
      }
    );

    // 将面板添加到Map中
    panelMap.set(viewType, panel);

    // 设置HTML内容
    let htmlContent = await this.getWebviewContent();
    // 替换html中的资源引用路径为https://格式
    const resourceUris = this.getPanelResourceUris(panel);
    htmlContent = htmlContent
      .replace("${chunkVendorsUri}", resourceUris.chunkVendors.toString())
      .replace("${myJsUri}", resourceUris[jsResourceKey].toString())
      .replace("${cssUri}", resourceUris.css.toString());

    panel.webview.html = htmlContent;

    // 处理面板关闭事件
    panel.onDidDispose(
      () => {
        // 从Map中移除已关闭的面板
        panelMap.delete(viewType);
      },
      null,
      this.context.subscriptions
    );

    // 处理来自webview的消息
    panel.webview.onDidReceiveMessage(
      (message) => {
        console.log("Panel received message:", message);
        // TODO 在这里处理面板特定的消息
      },
      undefined,
      this.context.subscriptions
    );
    vscode.window.setStatusBarMessage(`${title}已打开`, 3000);
  }

  /**
   * 读资源目录下的html文件内容
   * @param filePath 文件路径
   * @returns
   */
  private async readHtmlContent(filePath: string): Promise<string> {
    try {
      return await fs.promises.readFile(filePath, "utf8");
    } catch (error) {
      console.error("Error reading HTML file:", error);
      throw error;
    }
  }
  /**
   * @description 获取webview内容
   * @author dorado
   */
  private async getWebviewContent(): Promise<string> {
    try {
      const absPath = path.join(
        this.context.extensionPath,
        ...RESOURCES.WEBVIEW_BASE,
        ...RESOURCES.WEBVIEW.HTML.split("/")
      );
      let htmlContent: string = await this.readHtmlContent(absPath);
      return htmlContent;
    } catch (error) {
      vscode.window.showErrorMessage(`读取 HTML 文件失败: ${error}`);
    }
    return "";
  }
  /**
   * 获取vscode的资源URI
   */
  private getResourceUris(panel: vscode.WebviewView) {
    return {
      chunkVendors: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.JS.CHUNK_VENDORS.split("/")
        )
      ),
      sideBarJs: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.JS.SIDE_BAR.split("/")
        )
      ),
      css: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.CSS.split("/")
        )
      ),
    };
  }

  private getPanelResourceUris(panel: vscode.WebviewPanel) {
    return {
      codeAssistantJs: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.JS.CODE_ASSISTANT.split("/")
        )
      ),
      aiProgrammerJs: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.JS.AI_PROGRAMMER.split("/")
        )
      ),
      formDesignerJs: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.JS.FORM_DESIGNER.split("/")
        )
      ),
      chunkVendors: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.JS.CHUNK_VENDORS.split("/")
        )
      ),
      css: panel.webview.asWebviewUri(
        vscode.Uri.joinPath(
          this.context.extensionUri,
          ...RESOURCES.WEBVIEW_BASE,
          ...RESOURCES.WEBVIEW.CSS.split("/")
        )
      ),
    };
  }
}
/**
 * 资源路径常量
 * WEBVIEW_BASE资源路径根目录：/resources/webview/
 */
const RESOURCES = {
  WEBVIEW_BASE: ["resources", "webview"],
  ICONS: {
    LIGHT: "resources/dark/UI-editor-light.svg",
    DARK: "resources/dark/UI-editor-dark.svg",
  },
  WEBVIEW: {
    HTML: "tools.html",
    JS: {
      CHUNK_VENDORS: "js/chunk-vendors.js",
      SIDE_BAR: "js/sideBar.js",
      AI_PROGRAMMER: "js/aiProgrammer.js",
      CODE_ASSISTANT: "js/codeAssistant.js",
      FORM_DESIGNER: "js/formDesigner.js",
    },
    CSS: "assets/styles.css",
  },
} as const;
